function getPreviousLabel(node)
{
    var result = node.previousSibling;
    while (result != null &&
           result.tagName != "LABEL" &&
           result.tagName != "SPAN")
    {
        result = result.previousSibling;
    }
    return result;
}

var RegularExpression = {
	/** Not Latin1 any more but just all Unicode characters except control characters (BELL, etc.) */
    LATIN_1 : /^[^\u0000-\u0008\u000B\u000C\u000E-\u001F]+$/,

    TEXT : /[A-Za-z0-9\-\_\ \.\,\(\)\[\]\+"']+/,
    
    HOLDER: /^[a-zA-Z ]+$/,
    
    NAME : /^[a-zA-Z '-]+$/,

    EMAIL : /^((?=.{1,64}@)([a-zA-Z0-9_]+([\.\-\+][a-zA-Z0-9_]+)*))@((([a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9]){0,1}\.)+[a-zA-Z]{2,6})|(([2]([0-4][0-9]|([5][0-4]))|([1][0-9][0-9])|([0]?[1-9][0-9])|([0]?[0]?[1-9]))\.)(([2]([0-4][0-9]|([5][0-4]))|([1][0-9][0-9])|([0]?[1-9][0-9])|([0]?[0]?[0-9]))\.)(([2]([0-4][0-9]|([5][0-4]))|([1][0-9][0-9])|([0]?[1-9][0-9])|([0]?[0]?[0-9]))\.)(([2]([0-4][0-9]|([5][0-4]))|([1][0-9][0-9])|([0]?[1-9][0-9])|([0]?[0]?[1-9]))))$/,

    POST_CODE : /^[a-zA-Z0-9 \-]+$/,

    ALPHA : /^[a-zA-Z ]+$/,

    ALPHANUMERIC : /^[-a-zA-Z0-9_ \-]+$/,

    PHONE : /^\+?[0-9]+ *(\([0-9]{1,3}\))? *([0-9]+-)*[0-9]+$/,

    NUMBER : /(^\s*$|^\s*-?\s*\d+\s*$)/,

    POSITIVE: /^[0-9]*$/,
    
    CARD_NUMBER: /^\**[0-9]*$/,

    PASSWORD: /^[0-9a-zA-Z_]+$/,

    PROMOCODE: /^[A-Za-z0-9\-]+$/,
	
	STRICTNUMBER: /^\+?[0-9]*$/
};


var Validators = {

    CustomerInfo : {
        REQUIRED_FIELDS :
        {
            firstName:       true,
            lastName:         true,
            address1:        true,
            town:             true,
            postcode:         true,
            countryCode:     true,
            email:             true,
            phone:             true
        },
        CHECK_FOR_REQUIREMENT_FIELDS :
        {
            county:             true
        },

        MAX_LENGTH_FIELDS :
        {
            title:           20,
            firstName:         15,
            lastName:        25,
            company:         40,
            address1:        50,
            address2:         50,
            town:             25,
            county:             50,
            countryCode:     32,
            postcode:         10,
            email:             64,
            phone:             20,
            fax:             50
        },

        MIN_LENGTH_FIELDS :
        {
            firstName:         2,
            lastName:        2,
            company:         2,
            address1:        5,
            town:             2,
            email:             6,
            phone:             7
        },

        REGEXP_FIELDS :
        {
            email:             RegularExpression.EMAIL,
            phone:             RegularExpression.STRICTNUMBER,
            firstName:       RegularExpression.LATIN_1,
            lastName:        RegularExpression.LATIN_1,
            title:           RegularExpression.LATIN_1,
            postcode:        RegularExpression.POST_CODE,
            address1:        RegularExpression.ALPHANUMERIC,
            address2:        RegularExpression.ALPHANUMERIC
        },
        CONFIRM_FILEDS:
        {
        },
        ERROR_MESSAGES :
        {
            customized : true,
			
			INVALID :
            {
                phone: "Invalid Phone Number. No spaces or special characters allowed"
            }
        }
    },

    CreditCardDetails : {

        REQUIRED_FIELDS :
        {
            creditCardType:        true,
            cardNumber:            true,
            expireMonth:        true,
            expireYear:         true,
            securityCode:       true
        },

        MAX_LENGTH_FIELDS :
        {
            //cardHolder: 128,
            cardNumber: 19,
            securityCode: 3
        },

        MIN_LENGTH_FIELDS :
        {
            //cardHolder: 4,
            securityCode: 3
        },

        REGEXP_FIELDS :
        {
            //cardHolder: RegularExpression.CARD_HOLDER,
            cardNumber: RegularExpression.CARD_NUMBER,
            securityCode: RegularExpression.POSITIVE
        },

        CONFIRM_FILEDS:
        {
        },

        ERROR_MESSAGES :
        {
            customized : true,

            REQUIRED :
            {
                //cardNumber : getMessageByKey("requiredCardNumber"),
                expireMonth : getMessageByKey("requiredExpireMonth"),
                expireYear : getMessageByKey("requiredExpireYear"),
                creditCardType: getMessageByKey("requiredCreditCardType"),
                securityCode: getMessageByKey("requiredSecurityCode")
            },
            MAX_LENGTH :
            {
                //cardHolder: getMessageByKey("maxLenCardHolder"),
                cardNumber: getMessageByKey("maxLenCardNumber"),
                securityCode:getMessageByKey("maxlenSecurityCode")
            },
            MIN_LENGTH :
            {
                //cardHolder: getMessageByKey("minLenCardHolder"),
                securityCode:getMessageByKey("minLenSecurityCode")
            },
            INVALID :
            {
                //cardCardHolder: getMessageByKey("invalidCardHolder"),
                cardNumber: getMessageByKey("invalidCardNumber"),
                securityCode:getMessageByKey("invalidSecurityCode")
            },
            CONFIRMATION :
            {
            }
        }
    },

    CustomerRegistration : {
        NO_TRIM:
        {
            password: true,
            confirmPassword: true
        },

        REQUIRED_FIELDS :
        {
            userName:           true,
            password:            true,
            confirmPassword:    true,
            firstName:          true,
            lastName:           true,
            address1:           true,
            town:               true,
            postcode:            true,
            countryCode:        true,
            email:                true,
            confirmEmail:        true,
            phone:                true
            //			,confirmationCode:true
        },

        CHECK_FOR_REQUIREMENT_FIELDS :
        {
            county:             true
        },

        CONFIRM_FILEDS:
        {
            password: "confirmPassword",
            email : "confirmEmail"
        },

        MAX_LENGTH_FIELDS :
        {
            userName:        16,
            password:        32,
            confirmPassword:32,
            title:            20,
            firstName:        15,
            lastName:        25,
            company:    40,
            address1:     50,
            address2:     50,
            town:            25,
            county:            50,
            countryCode:    32,
            postcode:        10,
            email:            64,
            phone:             20,
            contactPhone:     50,
            fax:            50
            //			,confirmationCode:50
        },

        MIN_LENGTH_FIELDS :
        {
            userName: 3,
            password : 7,
            firstName:        2,
            lastName:        2,
            company:    2,
            address1:     5,
            town:            2,
            email:            6,
            phone:             7
        },

        REGEXP_FIELDS :
        {
            email:             RegularExpression.EMAIL,
            phone:             RegularExpression.STRICTNUMBER,
            firstName:       RegularExpression.LATIN_1,
            lastName:        RegularExpression.LATIN_1,
            title:           RegularExpression.LATIN_1,
            postcode:        RegularExpression.POST_CODE,
            userName:        RegularExpression.PASSWORD,
            password:        RegularExpression.PASSWORD,
            address1:        RegularExpression.ALPHANUMERIC,
            address2:        RegularExpression.ALPHANUMERIC,
            company:         RegularExpression.LATIN_1
        },

        ERROR_MESSAGES :
        {
            customized : true,

            REQUIRED :
            {
            },
            MAX_LENGTH :
            {
            	password: getMessageByKey("maxLenPassword")
            },
            MIN_LENGTH :
            {
            	password: getMessageByKey("minLenPassword")
            },
            INVALID :
            {
            	password: getMessageByKey("ivalidPassword"),
				phone: "Invalid Phone Number. No spaces or special characters allowed"
            },
            CONFIRMATION :
            {
            }
        }
    },

    CustomerLogin : {
        NO_TRIM:
        {
            password: true
        },

        REQUIRED_FIELDS :
        {
            userName:        true,
            password:        true
        },

        MAX_LENGTH_FIELDS :
        {
            userName:        16,
            password:        32
        },

        MIN_LENGTH_FIELDS :
        {
        },

        REGEXP_FIELDS :
        {
        }
        ,
        CONFIRM_FILEDS:
        {
        },

        ERROR_MESSAGES :
        {
            customized : false
        }
    },

    CustomerChangePassword : {
        NO_TRIM:
        {
            currentPassword:    true,
            password: 			true,
            confirmPassword: 	true
        },

        REQUIRED_FIELDS :
        {
            currentPassword:    true,
            password:           true,
            confirmPassword:    true
        },

        MAX_LENGTH_FIELDS :
        {
            currentPassword:    32,
            password:           32,
            confirmPassword:    32
        },

        MIN_LENGTH_FIELDS :
        {
            password:           7
        },

        REGEXP_FIELDS :
        {
            password:           RegularExpression.PASSWORD
        },

        CONFIRM_FILEDS:
        {
        	 password: "confirmPassword"
        },

        ERROR_MESSAGES :
        {
            customized : true,
            
            REQUIRED :
            {
            },
            MAX_LENGTH :
            {
            	password: getMessageByKey("maxLenPassword")
            },
            MIN_LENGTH :
            {
            	password: getMessageByKey("minLenPassword")
            },
            INVALID :
            {
            	password: getMessageByKey("ivalidPassword")
            },
            CONFIRMATION :
            {
            }
        }
    },

    CustomerRemindPassword : {
        REQUIRED_FIELDS :
        {
            email: true
        },

        MAX_LENGTH_FIELDS :
        {
            email: 255
        },

        MIN_LENGTH_FIELDS :
        {
        },

        REGEXP_FIELDS :
        {
            email:             RegularExpression.EMAIL
        },
        CONFIRM_FILEDS:
        {
        },
        ERROR_MESSAGES :
        {
            customized : false
        }
    },

    Enquiry : {
        REQUIRED_FIELDS :
        {
            name:        true,
            email:        true
        },

        MAX_LENGTH_FIELDS :
        {
            title:          20,
            name:           128,
            note:           2048,
            phone:          20,
            email:            64
        },

        MIN_LENGTH_FIELDS :
        {
            phone:          7,
            email:            6
        },

        REGEXP_FIELDS :
        {
            name:           RegularExpression.LATIN_1,
            phone:          RegularExpression.STRICTNUMBER,
            email:            RegularExpression.EMAIL
        },
        CONFIRM_FILEDS:
        {
        },
        ERROR_MESSAGES :
        {
            customized : true,
			
			INVALID :
            {
                phone: "Invalid Phone Number. No spaces or special characters allowed"
            }
        }
    },

    SearchProducts: {
        REQUIRED_FIELDS :
        {
            ssv: true
        },

        MAX_LENGTH_FIELDS :
        {
            ssv:    255
        },

        MIN_LENGTH_FIELDS :
        {
            ssv:    2
        },

        REGEXP_FIELDS :
        {
            ssv: RegularExpression.LATIN_1
        },
        CONFIRM_FILEDS:
        {
        },
        ERROR_MESSAGES :
        {
            customized : true,

            REQUIRED :
            {
                ssv: getMessageByKey("minLenSsv")
            },
            MAX_LENGTH :
            {
                ssv: getMessageByKey("maxLenSsv")
            },
            MIN_LENGTH :
            {
                ssv: getMessageByKey("minLenSsv")
            },
            INVALID :
            {
                ssv: getMessageByKey("invalidSsv")
            },
            CONFIRMATION :
            {
            }
        }
    },

    LocaytaInputFilter: {
        REQUIRED_FIELDS :
        {
            input: true
        },

        MAX_LENGTH_FIELDS :
        {
            input:    200
        },

        MIN_LENGTH_FIELDS :
        {
        },

        REGEXP_FIELDS :
        {
            input: RegularExpression.LATIN_1
        },
        CONFIRM_FILEDS:
        {
        },
        ERROR_MESSAGES :
        {
            customized : true,

            REQUIRED :
            {
                input: "pleaseEnter"
            },
            MAX_LENGTH :
            {
                input: "shouldNotExceed"
            },
            MIN_LENGTH :
            {
            },
            INVALID :
            {
                input: "containsIllegalCharacters"
            },
            CONFIRMATION :
            {
            }
        }
    },

    PromoCode : {
        REQUIRED_FIELDS :
        {
            promoCode:       true
        },

        MAX_LENGTH_FIELDS :
        {
            promoCode:       32
        },

        MIN_LENGTH_FIELDS :
        {
        },

        REGEXP_FIELDS :
        {
            promoCode: RegularExpression.PROMOCODE
        },
        CONFIRM_FILEDS:
        {
        },
        ERROR_MESSAGES :
        {
            customized : true,

            REQUIRED :
            {
                promoCode:getMessageByKey("requiredPromoCode")
            },
            MAX_LENGTH :
            {
                promoCode: getMessageByKey("maxLenPromoCode")
            },
            MIN_LENGTH :
            {
            },
            INVALID :
            {
                promoCode: getMessageByKey("invalidPromoCode")
            },
            CONFIRMATION :
            {
            }
        }
    }
};


function needToBeTrimmed(validationDesc, element)
{
    if (validationDesc.NO_TRIM != null && validationDesc.NO_TRIM != undefined)
    {
        if (validationDesc.NO_TRIM[element.name] != null && validationDesc.NO_TRIM[element.name] != undefined)
        {
            if (validationDesc.NO_TRIM[element.name])
            {
                return false;
            }
        }
    }

    return true;
}

function trimIfNecessary(validationDesc, element)
{
    if (needToBeTrimmed(validationDesc, element))
    {
        element.value = $.trim(element.value);
    }
}

function validateForm(form, validationDesc, errorOutput)
{

    if ($(".card_type").val() == "AMERICAN_EXPRESS") {
            Validators.CreditCardDetails.MAX_LENGTH_FIELDS.securityCode = 4;
            Validators.CreditCardDetails.MIN_LENGTH_FIELDS.securityCode = 4;
            } 
        else {
            Validators.CreditCardDetails.MAX_LENGTH_FIELDS.securityCode = 3;
            Validators.CreditCardDetails.MIN_LENGTH_FIELDS.securityCode = 3;
    }
    
    var isValid = true;
    var errorMessage = '';

    for (var i = 0; i < form.elements.length; i++)
    {
        var element = form.elements[i];
        if ((element.tagName != "INPUT" &&
            element.tagName != "SELECT" &&
            element.tagName != "TEXTAREA") ||
            (typeof $(element).attr("readonly") != 'undefined'))
        {
            continue;
        }

        var fieldLabel = '';
        var isRequired = validationDesc.REQUIRED_FIELDS[element.name];
        var isCheckForRequirement = false;
        if (validationDesc.CHECK_FOR_REQUIREMENT_FIELDS != null)
        {
            validationDesc.CHECK_FOR_REQUIREMENT_FIELDS[element.name];
        }
        var maxLength = validationDesc.MAX_LENGTH_FIELDS[element.name];
        var minLength = validationDesc.MIN_LENGTH_FIELDS[element.name];
        var regExp = validationDesc.REGEXP_FIELDS[element.name];
        var confirmFields = validationDesc.CONFIRM_FILEDS[element.name];
        var customMessage = validationDesc.ERROR_MESSAGES.customized;

        trimIfNecessary(validationDesc, element);

        var prevLabel = getPreviousLabel(element);
        if (prevLabel != null)
        {
            fieldLabel = prevLabel.innerHTML;
        }

        if (isCheckForRequirement && element.className == 'requiredParameter')
        {
            isRequired = true;
        }

        if (isRequired && element.value == '')
        {
            isValid = false;
            if (customMessage && COMMONS.isDefined(validationDesc.ERROR_MESSAGES.REQUIRED[element.name]))
            {
                errorMessage = validationDesc.ERROR_MESSAGES.REQUIRED[element.name];
            }
            else
            {
                errorMessage = getMessageByKey("isRequired",new Array(fieldLabel));
            }
            break;
        }
        if (maxLength != null && isValid)
        {
            if (element.value.length > maxLength)
            {
                isValid = false;
                if (customMessage && COMMONS.isDefined(validationDesc.ERROR_MESSAGES.MAX_LENGTH[element.name]))
                {
                    errorMessage = validationDesc.ERROR_MESSAGES.MAX_LENGTH[element.name];
                }
                else
                {
                    errorMessage = getMessageByKey("shouldNotExceed", new Array(fieldLabel, maxLength));
                }


                break;
            }
        }
        if (minLength != null && isValid && isRequired && element.value.length > 0)
        {
            if (element.value.length < minLength)
            {
                isValid = false;
                if (customMessage && COMMONS.isDefined(validationDesc.ERROR_MESSAGES.MIN_LENGTH[element.name]))
                {
                    errorMessage = validationDesc.ERROR_MESSAGES.MIN_LENGTH[element.name];
                }
                else
                {
                    errorMessage = getMessageByKey("shouldBeAtLeast", new Array(fieldLabel, minLength));
                }
                break;
            }
        }
        if (regExp != null && isValid)
        {
            if (element.value == null || element.value == '')
                continue;

            var match = element.value.match(regExp);
            if (! match)
            {
                isValid = false;
                if (customMessage && COMMONS.isDefined(validationDesc.ERROR_MESSAGES.INVALID[element.name]) )
                {
                    errorMessage = validationDesc.ERROR_MESSAGES.INVALID[element.name];
                }
                else
                {
                    errorMessage = getMessageByKey("isInvalid", new Array(fieldLabel));
                }
                break;
            }
        }
        if (confirmFields != null && isValid)
        {
            var confirmField = document.getElementsByName(confirmFields)[0];
            if (needToBeTrimmed(validationDesc, element))
            {
                confirmField.value = $.trim(confirmField.value);
            }

            if (element.value != confirmField.value)
            {
                isValid = false;
                var confirmationLabel = getPreviousLabel(confirmField).innerHTML;
                if (customMessage && COMMONS.isDefined(validationDesc.ERROR_MESSAGES.CONFIRMATION['all']) )
                {
                    errorMessage = getMessage(validationDesc.ERROR_MESSAGES.CONFIRMATION['all'],
                            new Array(fieldLabel, confirmationLabel));
                }
                else
                {
                    errorMessage = getMessageByKey("doNotMatch", new Array(fieldLabel, confirmationLabel));
                }

                break;
            }
        }
    }
    if (! isValid)
    {
        errorOutput.innerHTML = '<p class="error">' + errorMessage + '</p>';
    }
    return isValid;
}
